package edu.unika.aifb.graphindex.searcher.keyword.model;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

public class EntropyModel {
	private RelevanceModel queryRelevanceModel;
	private IndexReader indexReader;
	private IndexSearcher indexSearcher;
	
	private static final Logger log = Logger.getLogger(EntropyModel.class);
	
	public EntropyModel(RelevanceModel queryRelevanceModel, IndexReader indexReader, IndexSearcher indexSearcher){
		this.queryRelevanceModel = queryRelevanceModel;
		this.indexReader = indexReader;
		this.indexSearcher = indexSearcher;
	}
	
	public double calculateEntropyToDocument(RelevanceModel documentRelevanceModel) throws IOException{
		double entropy = 0;
		Map<String, Double> queryRM = queryRelevanceModel.getNormalizedTermFrequencies();
		Map<String, Double> documentRM = documentRelevanceModel.getNormalizedTermFrequencies();
		Map<String, Double> backgroundTermsProb = new HashMap<String, Double>();
		int hitKeywordsCount = 0;
		int hitTermsCount = 0;
		for(String term : queryRM.keySet()){
			double queryTermProb = queryRM.get(term);
			Double documentTermProbObj = documentRM.get(term);
			double documentTermProb = (documentTermProbObj != null) ? documentTermProbObj : 0 ;
			Double backgroundTermProb = backgroundTermsProb.get(term);
			if(backgroundTermProb == null){
				TopDocs topDocs = indexSearcher.search(new TermQuery(new Term(Constant.TERM_FIELD, term)), 1);
				String prob = indexReader.document(topDocs.scoreDocs[0].doc).getFieldable(Constant.PROB_FIELD).stringValue();
				backgroundTermProb = Double.parseDouble(prob);
				backgroundTermsProb.put(term, backgroundTermProb);
			}
			
			if(documentTermProb != 0){
				if(queryRelevanceModel.getKeywords().contains(term))
					hitKeywordsCount++;
				else
					hitTermsCount++;
			}
			entropy += (queryTermProb * (0.9 * documentTermProb + 0.1 * backgroundTermProb));
		}
		
		if(hitKeywordsCount > 1)
			entropy *= hitKeywordsCount;
		if(hitKeywordsCount == queryRelevanceModel.getKeywords().size())
			entropy *= hitKeywordsCount;
//		
//		if(hitTermsCount > 0)
//			entropy = entropy*hitTermsCount*0.1;
			
		
		return Math.abs(entropy);
	}
}
